﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Perovich.GameObjects.Interfaces;
using Perovich.GameObjects.Components;

namespace Perovich.GameObjects.Components
{
    public sealed class ComponentFactory : Factory
    {
        public static EntityComponent Create(Type type, IEntity owner, bool overwrite, params object[] parameters)
        {
            ConstructorInfo bestMatch = GetBestMatchingConstructor(type, parameters);

            object o = null;

            try
            {
                o = bestMatch.Invoke(parameters);
            }
            catch (TargetParameterCountException)
            {
                throw;
            }

            EntityComponent component = o as EntityComponent;

            component.Owner = owner;
            owner.Add(component, overwrite);

            return o as EntityComponent;
        }

        public static T Create<T>(IEntity owner) where T : EntityComponent
        {
            return Create<T>(owner, new object[] { });
        }

        public static T Create<T>(IEntity owner, params object[] parameters) where T : EntityComponent
        {
            return Create<T>(owner, false, parameters);
        }

        public static T Create<T>(IEntity owner, bool overwrite, params object[] parameters) where T : EntityComponent
        {
            ConstructorInfo bestMatch = GetBestMatchingConstructor(typeof(T), parameters);

            object o = null;

            try
            {
                o = bestMatch.Invoke(parameters);
            }
            catch (TargetParameterCountException tpce)
            {
                throw tpce;
            }

            EntityComponent component = o as EntityComponent;

            component.Owner = owner;
            owner.Add(component, overwrite);

            return o as T;
        }
    }
}
